<?php


namespace app\index\controller;


use app\admin\service\RbacService;
use app\common\controller\CommonController;
use app\common\controller\platform\MpMini;
use app\common\enum\MainEnum;
use app\common\exception\NotFoundException;
use app\common\exception\ParameterFailedException;
use app\common\model\AddressModel;
use app\common\model\CartModel;
use app\common\model\OrderListModel;
use app\common\model\OrderListRefundModel;
use app\common\model\OrderModel;
use app\common\model\PackageCompanyModel;
use app\common\model\ProductSkuModel;
use app\common\model\UserCouponModel;
use app\common\service\Lang;
use app\common\service\Pay;
use app\common\service\RabbitMQBusinessInterface;
use app\common\service\SF;
use app\common\validate\OrderValidate;
use think\facade\Config;
use think\facade\Db;
use think\Request;

class OrderController extends CommonController
{
    public function getOrderById(Request $request)
    {

        $params = self::getParam([
            'id',
        ]);
        (new OrderValidate())->goCheck(__FUNCTION__, $params);
        $where[] = [
            'user_id', '=', $request->userModel->getData('id'),
        ];
        $where[] = [
            'id', '=', $params['id'],
        ];
        $model   = (new OrderModel())->getOrder($where);
        if (!$model) {
            throw new NotFoundException();
        }
        $res = $model->toArray();
        return retJson(Lang::GETDone, $res);
    }

    public function getOrderList(Request $request)
    {

        $models = (new OrderModel())->getOrderList([
            [
                'user_id', '=', $request->userModel->getData('id'),
            ],
        ]);
        if ($models->isEmpty()) {
            $res = [];
        }
        else {
            $res = $models->toArray();
        }
        return retJson(Lang::GETDone, $res);
    }

    public function getOrderPackage(Request $request)
    {

        $params = self::getParam([
            'id',
        ]);
        (new OrderValidate())->goCheck(__FUNCTION__, $params);
        $where = [
            [
                'user_id', '=', $request->userModel->getData('id'),
            ], [
                'id', '=', $params['id'],
            ],
        ];
        $model = (new OrderModel())->getOrder($where);
        if (!$model) {
            throw new NotFoundException();
        }
        $res = $model->toArray();
        if (!$res['package_company_id'] || !isset($res['packageCompanyInfo']) || !$res['package_nb']) {
            throw new ParameterFailedException(['msg' => '该订单未发货']);
        }
        if ($res['packageCompanyInfo']['identifier'] === 'SF') {
            $data               = [
                'language'       => '0', #返回描述语语言0：中文 1：英文 2：繁体
                'trackingType'   => '1', #查询号类别:  1:根据顺丰运单号查询 2:根据客户订单号查询
                'trackingNumber' => ['SF441003077850'], #查询号:trackingType=1,则此值为顺丰运单号如果trackingType=2,则此值为客户订单号
                'methodType'     => '1',
            ];
            $res['packageInfo'] = SF::getRouteInfo($data);
        }

        return retJson(Lang::GETDone, $res);
    }

    public function postOrderPlace(Request $request)
    {

        $params = self::getParam([
            'address_id', 'cart_ids', 'coupon_id', 'remark',
        ]);
        (new OrderValidate())->goCheck(__FUNCTION__, $params);
        Db::startTrans();
        try {
            if (!is_array($params['cart_ids'])) {
                $params['cart_ids'] = explode(',', $params['cart_ids']);
            }
            $cartModels = (new CartModel())->getUserCartByIds([
                [
                    'id', 'in', $params['cart_ids'],
                ], [
                    'user_id', '=', $request->userModel->getData('id'),
                ],
            ]);
            if (count($cartModels) !== count($params['cart_ids'])) {
                throw new ParameterFailedException(['msg' => '购物车数据有误']);
            }

            $buyProductIds = [];
            foreach ($cartModels as $cartModel) {
                if (!$cartModel->productInfo || !$cartModel->productSkuInfo) {
                    throw new ParameterFailedException(['msg' => '商品数据有误']);
                }

                if ($cartModel->productInfo->getData('status') !== MainEnum::PRODUCT_STATUS['已上架']) {
                    throw new ParameterFailedException(['msg' => '商品' . $cartModel->productInfo->getData('name') . '已下架']);
                }
                $buyProductIds[] = $cartModel->getData('product_id');
            }
            $buyProductIds = array_unique($buyProductIds);

            $addressModel = (new AddressModel())->getAddress([
                [
                    'user_id', '=', $request->userModel->getData('id'),
                ], [
                    'id', '=', $params['address_id'],
                ],
            ]);
            if (!$addressModel) {
                throw new ParameterFailedException(['msg' => '地址不存在']);
            }

            $priceTotal        = 0;
            $discountPrice     = 0;   #总优惠的钱
            $discountPriceDesc = [];  #总优惠说明
            $pricePackage      = 0;   #快递费

            //生成订单号
            $orderNb = getRandomStr();
            $model   = new OrderModel();

            $orderListPrepareSaveData = [];
            $packagePrice             = 0;

            foreach ($cartModels as &$cartModel) {
                /**
                 * 判断并且扣减库存
                 */
                if (!ProductSkuModel::deductStock($cartModel->productSkuInfo, $cartModel->getData('count'))) {
                    throw new ParameterFailedException(['msg' => $cartModel->productSkuInfo->getData('product_sku_name') . '已无库存，无法购买']);
                }
                $priceTotalTemp = $cartModel->getData('count') * $cartModel->productSkuInfo->getData('price');
                $priceTotalTemp = $priceTotalTemp <= 0 ? 0 : $priceTotalTemp;
                $priceTotal     += $priceTotalTemp <= 0 ? 0 : $priceTotalTemp;
                //                if ($packagePriceTemp > 0) {
                //                    $discountPriceDesc .= "规格{$cartModel->productSkuInfo->getData('sku_name')}快递费用：" . $packagePriceTemp . '|';
                //                }
                $orderListPrepareSaveData [] = [
                    'user_id' => $request->userModel->getData('id'), 'order_nb' => $orderNb, 'product_name' => $cartModel->productInfo->getData('name'), 'product_sku_logo_url' => $cartModel->productInfo->getData('logo_url'), 'product_sku_name' => $cartModel->productSkuInfo->getData('sku_name'), 'product_sku_price' => $cartModel->productSkuInfo->getData('price'),

                    'count_total' => $cartModel->getData('count'), 'price_total' => $priceTotalTemp, 'price_discount' => 0, 'price_discount_desc' => [], 'price_package' => $pricePackage,
                ];
                $cartModel->delete_time      = NOW_TIME;
                $cartModel->save();
            }

            //检查优惠券
            if (is_numeric($params['coupon_id'])) {
                $userCouponModel = (new UserCouponModel())->getUserCoupon([
                    [
                        'user_id', '=', $request->userModel->getData('id'),
                    ], [
                        'coupon_id', '=', $params['coupon_id'],
                    ],
                ]);
                if (!$userCouponModel) {
                    throw new ParameterFailedException(['msg' => '优惠券不存在']);
                }
                //判断优惠券是否可用
                $userCouponModelArr = $userCouponModel->toArray();

                if (!UserCouponModel::okUse($userCouponModelArr, $buyProductIds, $priceTotal)) {
                    throw new ParameterFailedException(['msg' => '优惠券不可用']);
                }
                switch ($userCouponModel->couponInfo->getData('type')) {
                    case MainEnum::COUPON_TYPE['满减']:
                        #满减
                        $temp                      = $userCouponModel->couponInfo->getData('type_jian_price');
                        $discountPrice             += $temp;
                        $discountPriceDesc[]       = ['满减优惠券' => $temp];
                        $model->coupon_id          = $userCouponModel->getData('coupon_id');
                        $model->coupon_price       = $temp;
                        $model->coupon_status      = MainEnum::ORDER_COUPON_STATUS['已使用'];
                        $userCouponModel->status   = MainEnum::COUPON_USER_STATUS['已使用'];
                        $userCouponModel->use_time = NOW_TIME;
                        $userCouponModel->save();
                        self::orderDiscountSharing($priceTotal, $temp, '满减优惠券', $orderListPrepareSaveData);
                        unset($temp);
                        break;
                    case MainEnum::COUPON_TYPE['折扣']:
                        $temp                      = $userCouponModel->couponInfo->getData('type_discount_price') / 100 * $priceTotal;
                        $discountPrice             += $temp;
                        $discountPriceDesc[]       = ['折扣优惠券' => $temp];
                        $model->coupon_id          = $userCouponModel->getData('coupon_id');
                        $model->coupon_price       = $temp;
                        $model->coupon_status      = MainEnum::ORDER_COUPON_STATUS['已使用'];
                        $userCouponModel->status   = MainEnum::COUPON_USER_STATUS['已使用'];
                        $userCouponModel->use_time = NOW_TIME;
                        $userCouponModel->save();
                        self::orderDiscountSharing($priceTotal, $temp, '折扣优惠券', $orderListPrepareSaveData);
                        unset($temp);
                        break;
                    case MainEnum::COUPON_TYPE['随机减金额']:
                        $temp = (float)$userCouponModel->getData('type_random_price');
                        if (in_array($temp, [
                            0, 0.00, null,
                        ], true)) {
                            $temp                               = random_int($userCouponModel->couponInfo->getData('type_random_min_price') * 100, $userCouponModel->couponInfo->getData('type_random_max_price') * 100) / 100;
                            $userCouponModel->type_random_price = $temp;
                        }
                        $discountPrice             += $temp;
                        $discountPriceDesc         = ['随机减优惠券' => $temp];
                        $model->coupon_id          = $userCouponModel->getData('coupon_id');
                        $model->coupon_price       = $temp;
                        $model->coupon_status      = MainEnum::ORDER_COUPON_STATUS['已使用'];
                        $userCouponModel->status   = MainEnum::COUPON_USER_STATUS['已使用'];
                        $userCouponModel->use_time = NOW_TIME;
                        $userCouponModel->save();
                        self::orderDiscountSharing($priceTotal, $temp, '随机减优惠券', $orderListPrepareSaveData);
                        unset($temp);
                        break;
                    default:
                }
            }

            foreach ($orderListPrepareSaveData as &$item) {
                # todo 测试
                #$item['price_pay']    = 0.01;
                $temp                 = $item['price_total'] - $item['price_discount'];
                $item['price_pay']    = $temp <= 0 ? 0 : $temp;
                $model->count_total   += $item['count_total'];
                $model->price_package += $item['price_package'];
            }

            $model->user_id                = $request->userModel->getData('id');
            $model->nb                     = $orderNb;
            $model->status                 = MainEnum::ORDER_STATUS_WAIT_PAY;
            $model->receiver_name          = $addressModel->getData('name');
            $model->receiver_mobile_number = $addressModel->getData('mobile_number');
            $model->receiver_address       = $addressModel->getData('province') . $addressModel->getData('city') . $addressModel->getData('area') . $addressModel->getData('detail');
            $model->product_name           = $cartModel->productInfo->getData('name');
            $model->product_logo_url       = $cartModel->productInfo->getData('logo_url');
            $model->mch_id                 = Config::get('main.wx.mch_id');
            $model->price_total            = $priceTotal;
            $model->price_discount         = $discountPrice;
            $model->price_discount_desc    = $discountPriceDesc;
            $model->price_pay              = $priceTotal - $discountPrice;
            $model->remark                 = $params['remark'];

            $platform_specific        = basename(str_replace('\\', '/', get_class(new MpMini())));
            $model->platform_specific = $platform_specific;

            //            vd($model->toArray());
            (new OrderListModel())->saveAll($orderListPrepareSaveData);
            $payRes                = (new Pay())->pay($model->getData('nb'), $model->getData('price_pay'), $request->userPlatformModel->getData('platform_open_id'), $cartModel->productInfo->getData('name') . '等');
            $model->wx_prepay_info = $payRes;
            $model->save();

            Db::commit();
            return retJson(Lang::POSTDone, $payRes);
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw $e;
        }
    }

    /**
     * @param $priceTotal float 总价格
     * @param $discountTotal float 优惠总价格
     * @param $text string
     * @param $orderListData array
     *
     * @Author: Li Guo Xin <guoxinlee129@gmail.com>
     * @Date: 2020/12/10
     * @Time: 1:53
     */
    public static function orderDiscountSharing($priceTotal, $discountTotal, $text, &$orderListData)
    {
        //总优惠多少
        //单个比例
        //分配的总人头数
        $count   = count($orderListData);
        $sortArr = [];
        foreach ($orderListData as $key => $orderListItem) {
            $sortArr[] = $orderListItem['price_total'];
        }
        array_multisort($sortArr, SORT_ASC, $orderListData);
        $discountUse = 0;
        foreach ($orderListData as $key => &$orderListItem) {
            $bili = round($orderListItem['price_total'] / $priceTotal, 2);
            if ($key === $count - 1) {
                $temp = round($discountTotal - $discountUse, 2);
            }
            else {
                $temp = round($bili * $discountTotal, 2);
            }
            $orderListItem['price_discount']        += $temp;
            $orderListItem['price_discount_desc'][] = [$text => $temp];
            $discountUse                            += $temp;
            unset($temp);
        }
        //        vd($discountUse, $priceTotal, $discountTotal, $orderListData);
    }

    public function putOrderCancel(Request $request)
    {
        $params = self::getParam([
            'id', 'cancel_desc',
        ]);
        (new OrderValidate())->goCheck(__FUNCTION__, $params);
        Db::startTrans();
        try {
            $model = (new OrderModel())->getOrder([
                [
                    'id', '=', $params['id'],
                ], [
                    'user_id', '=', $request->userModel->getData('id'),
                ],
            ]);
            if (!$model) {
                throw new NotFoundException();
            }

            if ($model->getData('status') !== MainEnum::ORDER_STATUS_WAIT_PAY) {
                throw new ParameterFailedException(['msg' => '订单状态不正确']);
            }
            foreach ($model->orderListInfo as $item) {
                if ($item->getData('status') !== MainEnum::ORDER_LIST_REFUND_WAIT) {
                    throw new ParameterFailedException(['msg' => '订单状态不正确']);
                }
            }

            $model->status      = MainEnum::ORDER_STATUS_CANCEL;
            $model->cancel_desc = $params['cancel_desc'];
            $model->cancel_time = NOW_TIME;
            $model->save();

            Db::commit();

            return retJson(Lang::Done);
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw $e;
        }
    }

    public function putOrderRefund(Request $request)
    {
        $params = self::getParam([
            'id', 'nb', 'list_id', 'qs_status', 'type', 'reason', 'reason_desc', 'reason_desc_img_url', 'tk_price',
        ]);
        if ($params['tk_price'] <= 0) {
            throw new ParameterFailedException(['msg' => '退款金额有误']);
        }
        (new OrderValidate())->goCheck(__FUNCTION__, $params);
        Db::startTrans();
        try {
            $where[] = [
                'nb', '=', $params['nb'],
            ];
            $where[] = [
                'id', '=', $params['id'],
            ];
            $where[] = [
                'user_id', '=', $request->userModel->getData('id'),
            ];
            $model   = (new OrderModel())->getOrder($where);
            if (!$model) {
                throw new NotFoundException();
            }
            $has = false;
            foreach ($model->orderListInfo as $orderListModel) {
                if ($orderListModel->getData('id') === (int)$params['list_id']) {
                    if ($orderListModel->getData('price_pay') < $params['tk_price']) {
                        throw new ParameterFailedException(['msg' => '退款金额有误']);
                    }
                    foreach ($orderListModel->refundInfo as $refundModel) {
                        if ($refundModel->getData('order_list_id') === (int)$params['list_id']) {
                            //找到对应的退款list_id
                            if (in_array($refundModel->getData('status'), [
                                MainEnum::ORDER_LIST_REFUND_ING, MainEnum::ORDER_LIST_REFUND_DAILURU, MainEnum::ORDER_LIST_REFUND_DAISHOUHUO, MainEnum::ORDER_LIST_REFUND_DAIYANHUO, MainEnum::ORDER_LIST_REFUND_WAIT_PAY, MainEnum::ORDER_LIST_REFUND_DONE,
                            ], true)) {
                                throw new ParameterFailedException(['msg' => '该规格不允许退款']);
                            }
                        }
                    }
                    $has = true;
                    break;
                }
            }
            if (!$has) {
                throw new NotFoundException(['msg' => '商品规格不存在']);
            }

            $refundModel                      = new OrderListRefundModel();
            $refundModel->user_id             = $request->userModel->getData('id');
            $refundModel->order_nb            = $params['nb'];
            $refundModel->order_nb            = $params['nb'];
            $refundModel->order_list_id       = $params['list_id'];
            $refundModel->order_list_id       = $params['list_id'];
            $refundModel->qs_status           = $params['qs_status'];
            $refundModel->tk_type             = $params['type'];
            $refundModel->reason              = $params['reason'];
            $refundModel->reason_desc         = $params['reason_desc'];
            $refundModel->reason_desc_img_url = $params['reason_desc_img_url'];
            $refundModel->refund_price        = $params['tk_price'];
            $refundModel->status              = MainEnum::ORDER_LIST_REFUND_ING;
            $refundModel->save();

            Db::commit();

            return retJson(Lang::Done);
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw $e;
        }
    }

    public function putOrderRefundLuru(Request $request)
    {
        $params = self::getParam([
            'list_id', 'package_company_id', 'package_nb',
        ]);
        (new OrderValidate())->goCheck(__FUNCTION__, $params);
        Db::startTrans();
        try {
            $where[] = [
                'order_list_id', '=', $params['list_id'],
            ];
            $where[] = [
                'status', '=', MainEnum::ORDER_LIST_REFUND_DAILURU,
            ];
            $where[] = [
                'user_id', '=', $request->userModel->getData('id'),
            ];
            $model   = (new OrderListRefundModel())->getRefund($where);
            if (!$model) {
                throw new NotFoundException();
            }

            $packageCompanyModel = (new PackageCompanyModel())->where('id', $params['package_company_id'])->find();
            if (!$packageCompanyModel) {
                throw new NotFoundException(['msg' => '快递公司不存在']);
            }

            $model->package_company_id = $params['package_company_id'];
            $model->package_nb         = $params['package_nb'];
            $model->status             = MainEnum::ORDER_LIST_REFUND_DAISHOUHUO;
            $model->save();

            Db::commit();

            return retJson(Lang::Done);
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw $e;
        }
    }

    public function putOrderSignFor(Request $request)
    {
        $params = self::getParam([
            'id',
        ]);
        (new OrderValidate())->goCheck(__FUNCTION__, $params);
        Db::startTrans();
        try {
            $model = (new OrderModel())->where('id', $params['id'])->where('user_id', $request->userModel->getData('id'))->find();
            if (!$model) {
                throw new NotFoundException();
            }

            if ($model->getData('status') !== MainEnum::ORDER_STATUS_WAIT_SIGN_FOR) {
                throw new ParameterFailedException(['msg' => '订单状态不正确']);
            }

            $model->status        = MainEnum::ORDER_STATUS_SIGN_FOR_ED;
            $model->sign_for_time = NOW_TIME;
            $model->save();

            Db::commit();

            return retJson(Lang::Done);
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw $e;
        }
    }
}